package com.ssy.lingxi.order.serviceimpl.im;

import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.constant.order.OrderTypeEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.order.entity.OrderDO;
import com.ssy.lingxi.order.model.constant.OrderOuterStatusEnum;
import com.ssy.lingxi.order.model.constant.OrderServiceContants;
import com.ssy.lingxi.order.model.vo.basic.response.DropdownItem;
import com.ssy.lingxi.order.model.vo.im.request.ImOrderPageVO;
import com.ssy.lingxi.order.model.vo.im.response.ImOrderVO;
import com.ssy.lingxi.order.repository.OrderRepository;
import com.ssy.lingxi.order.service.base.IBaseCacheService;
import com.ssy.lingxi.order.service.base.IBaseOrderService;
import com.ssy.lingxi.order.service.im.IOrderCommunicationService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单Im通信相关接口实现类
 *
 * @author 万宁
 * @version 2.0.0
 * @date 2021-07-15
 */
@Service
public class OrderCommunicationServiceImpl implements IOrderCommunicationService {
    @Resource
    private IBaseCacheService baseCacheService;

    @Resource
    private IBaseOrderService baseOrderService;

    @Resource
    private OrderRepository orderRepository;

    /**
     * 获取订单类型列表
     *
     * @param headers HttpHeader信息
     * @return 前端显示的下拉菜单
     */
    @Override
    public Wrapper<List<DropdownItem>> listOrderTypes(HttpHeaders headers) {
        baseCacheService.needLoginFromBusinessPlatform(headers);
        return Wrapper.success(baseOrderService.listOrderTypes());
    }

    /**
     * 分页查询用户订单列表
     *
     * @param headers HttpHeader信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<ImOrderVO>> pageOrders(HttpHeaders headers, ImOrderPageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);

        Pageable pageable = PageRequest.of(pageVO.getCurrent() - 1 , pageVO.getPageSize(), Sort.by("id").descending());
        Specification<OrderDO> specification = (Specification<OrderDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            //根据当前用户角色类型来判断当前用户是供应商，还是采购商
            if (loginUser.getMemberRoleType().equals(RoleTypeEnum.SERVICE_PROVIDER.getCode())) {
                list.add(criteriaBuilder.equal(root.get("vendorMemberId").as(Long.class), loginUser.getMemberId()));
                list.add(criteriaBuilder.equal(root.get("vendorRoleId").as(Long.class), loginUser.getMemberRoleId()));
                list.add(criteriaBuilder.equal(root.get("buyerMemberId").as(Long.class), pageVO.getMemberId()));

                //不要待提交的订单
                list.add(criteriaBuilder.notEqual(root.get("outerStatus").as(Integer.class), OrderOuterStatusEnum.TO_SUBMIT.getCode()));

            } else {
                list.add(criteriaBuilder.equal(root.get("buyerMemberId").as(Long.class), loginUser.getMemberId()));
                list.add(criteriaBuilder.equal(root.get("buyerRoleId").as(Long.class), loginUser.getMemberRoleId()));
                list.add(criteriaBuilder.equal(root.get("vendorMemberId").as(Long.class), pageVO.getMemberId()));
            }

            if(pageVO.getOrderType() != null) {
                list.add(criteriaBuilder.equal(root.get("orderType").as(Integer.class), pageVO.getOrderType()));
            }

            if (StringUtils.hasLength(pageVO.getStartDay())) {
                list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), LocalDateTime.parse(pageVO.getStartDay().concat(" 00:00:00"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
            }

            if (StringUtils.hasLength(pageVO.getEndDay())) {
                list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), LocalDateTime.parse(pageVO.getEndDay().concat(" 23:59:59"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
            }

            if (StringUtils.hasLength(pageVO.getOrderNo())) {
                list.add(criteriaBuilder.like(root.get("orderNo").as(String.class), "%" + pageVO.getOrderNo().trim() + "%"));
            }

            if (StringUtils.hasLength(pageVO.getDigest())) {
                list.add(criteriaBuilder.like(root.get("digest").as(String.class), "%" + pageVO.getDigest().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<OrderDO> pageList = orderRepository.findAll(specification, pageable);
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            ImOrderVO orderVO = new ImOrderVO();
            orderVO.setOrderId(order.getId());
            orderVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            orderVO.setOrderNo(order.getOrderNo());
            orderVO.setDigest(order.getDigest());
            orderVO.setOrderType(order.getOrderType());
            orderVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            orderVO.setOuterStatus(order.getOuterStatus());
            orderVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            orderVO.setProductAmount(order.getProductAmount());
            return orderVO;
        }).collect(Collectors.toList())));
    }
}
